package com.jiao.syntax.entity;

import com.jiao.syntax.enums.TokenKind;
import lombok.Getter;
import lombok.Setter;

/**
 * @Author: vincent.jiao
 * @Date: 2021/4/19
 */
public class Token {
    @Getter
    @Setter
    TokenKind kind;

    @Getter
    String dataStr;

    Object data;
    @Getter
    int startPos;
    @Getter
    int endPos;

    /**
     * 没有令牌的特定数据时使用的构造方法
     * (=.>. or '+' 子类)
     * @param startPos the exact start
     * @param endPos the index to the last character
     */
    public Token(TokenKind tokenKind, int startPos, int endPos) {
        this.kind = tokenKind;
        this.startPos = startPos;
        this.endPos = endPos;
    }

    public Token(TokenKind tokenKind, char[] tokenData, int startPos, int endPos) {
        this(tokenKind, startPos, endPos);
        this.dataStr = new String(tokenData);
    }

    public Token(TokenKind tokenKind, String dataStr, int startPos, int endPos) {
        this(tokenKind, startPos, endPos);
        this.dataStr = dataStr;
    }


    public boolean isIdentifier() {
        return (this.kind == TokenKind.IDENTIFIER);
    }

    public boolean isNumericRelationalOperator() {
        return (this.kind == TokenKind.GT || this.kind == TokenKind.GE || this.kind == TokenKind.LT ||
                this.kind == TokenKind.LE || this.kind==TokenKind.EQ || this.kind==TokenKind.NE);
    }

    public boolean isRangeIdentifier() {
        return (this.kind == TokenKind.BETWEEN || this.kind == TokenKind.IN || this.kind == TokenKind.NOTIN
                 );
    }

    public boolean isRelationOperator() {
        return (this.kind == TokenKind.BETWEEN || this.kind == TokenKind.IN
                 );
    }

    public static boolean isSymbol(Token token){
        for (TokenKind item : TokenKind.SYMBOL_LIST) {
            if(item.equals(token.getKind())){
                return true;
            }
        }

        return false;
    }
    public static boolean isPrecompile(Token token){
        for (TokenKind item : TokenKind.PRECOMPILE_LIST) {
            if(item.equals(token.getKind())){
                return true;
            }
        }

        return false;
    }

    public static boolean isRelation(Token token){
        for (TokenKind item : TokenKind.RELATION_LIST) {
            if(item.equals(token.getKind())){
                return true;
            }
        }

        return false;
    }

    public static boolean isField(Token token){
        return TokenKind.FIELD.equals(token.getKind());
    }

    public static boolean isOperation (Token token){
        for (TokenKind item : TokenKind.OPERATION_LIST) {
            if(item.equals(token.getKind())){
                return true;
            }
        }

        return false;
    }
    public static boolean isValueType(Token token){
        for (TokenKind item : TokenKind.VALUE_LIST) {
            if(item.equals(token.getKind())){
                return true;
            }
        }

        return false;
    }

    public String stringValue() {
        return (this.dataStr != null ? this.dataStr : "");
    }
    public <T> T getValue() {
        return (T) data;
    }
}
